package com.think.cloud.thinkshop.mall.service.cart.impl;


import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.think.cloud.thinkshop.common.enums.RabbitMessageTypeEnum;
import com.think.cloud.thinkshop.mall.controller.app.cart.vo.AddShopCartReqVO;
import com.think.cloud.thinkshop.mall.controller.app.cart.vo.MyCartRespVO;
import com.think.cloud.thinkshop.mall.controller.app.cart.vo.ShopCartRespVO;
import com.think.cloud.thinkshop.mall.controller.app.cart.vo.UpdateShopCartReqVO;
import com.think.cloud.thinkshop.mall.controller.app.coupon.dto.CartCouponDTO;
import com.think.cloud.thinkshop.mall.controller.app.coupon.vo.CartCouponRespVO;
import com.think.cloud.thinkshop.mall.controller.app.order.vo.AppOrderCartRespVO;
import com.think.cloud.thinkshop.mall.convert.cart.ShopCartConvert;
import com.think.cloud.thinkshop.mall.domain.Product;
import com.think.cloud.thinkshop.mall.domain.ProductAttrValue;
import com.think.cloud.thinkshop.mall.domain.ShopCart;
import com.think.cloud.thinkshop.mall.enums.common.CommonWhetherEnum;
import com.think.cloud.thinkshop.mall.mapper.ProductAttrValueMapper;
import com.think.cloud.thinkshop.mall.mapper.ShopCartMapper;
import com.think.cloud.thinkshop.mall.rabbit.producer.MessageProducer;
import com.think.cloud.thinkshop.mall.service.cart.AppShopCartService;
import com.think.cloud.thinkshop.mall.service.coupon.AppProductCouponRelationService;
import com.think.cloud.thinkshop.mall.service.product.AppProductService;
import com.think.common.core.exception.enums.ErrorCode;
import com.think.common.core.exception.util.ServiceExceptionUtil;
import com.think.common.core.utils.PageUtils;
import com.think.common.core.web.page.TableDataInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 购物车Service业务层处理
 *
 * @author zkthink
 * @date 2024-05-17
 */
@Service
public class AppShopCartServiceImpl implements AppShopCartService {
    @Autowired
    private ShopCartMapper shopCartMapper;

    @Autowired
    private AppProductService appProductService;

    @Autowired
    private ProductAttrValueMapper productAttrValueMapper;

    @Autowired
    private MessageProducer messageProducer;

    @Autowired
    private AppProductCouponRelationService appProductCouponRelationService;

    @Override
    public Long addCart(AddShopCartReqVO vo) {
        // 校验商品状态
        appProductService.checkProduct(vo.getProductId());
        // 查询规格是否在购物车存在
        ShopCart shopCart = shopCartMapper.selectOne(new LambdaQueryWrapper<ShopCart>()
                .eq(ShopCart::getUserId, vo.getUserId()).eq(ShopCart::getSkuId, vo.getSkuId())
                .eq(ShopCart::getIsPay, CommonWhetherEnum.NO.getValue())
                .eq(ShopCart::getIsNew, CommonWhetherEnum.NO.getValue()));
        // 立即购买或新增
        if (CommonWhetherEnum.YES.getValue().equals(vo.getIsNew()) || ObjectUtil.isNull(shopCart)) {
            // 校验库存
            appProductService.checkStock(vo.getSkuId(), vo.getNum());
            shopCart = ShopCartConvert.INSTANCE.convert(vo);
            // 保存购物车信息
            shopCartMapper.insert(shopCart);
        } else {
            // 合并数量
            Integer num = vo.getNum() + shopCart.getNum();
            // 校验库存
            appProductService.checkStock(vo.getSkuId(), num);
            shopCart.setNum(num);
            shopCartMapper.updateById(shopCart);
        }
        //触发自动客户分群
        messageProducer.sendMessage(String.valueOf(vo.getUserId()), RabbitMessageTypeEnum.MEMBER_GROUP_UPDATE_BY_USER_ACTION);
        return shopCart.getCartId();
    }

    @Override
    public void updateCart(UpdateShopCartReqVO vo) {
        ShopCart cart = shopCartMapper.selectById(vo.getCartId());
        if (ObjectUtil.isNull(cart) || !cart.getUserId().equals(vo.getUserId()))
            throw ServiceExceptionUtil.exception(ErrorCode.SHOP_CART_NOT_EXIST_ERROR);
        // 校验商品状态
        appProductService.checkProduct(cart.getProductId());
        // 校验库存
        appProductService.checkStock(cart.getSkuId(), vo.getNum());
        cart.setNum(vo.getNum());
        // 更新购物车信息
        shopCartMapper.updateById(cart);
        //触发自动客户分群
        messageProducer.sendMessage(String.valueOf(vo.getUserId()), RabbitMessageTypeEnum.MEMBER_GROUP_UPDATE_BY_USER_ACTION);
    }

    @Override
    public TableDataInfo getMyCart(Long userId) {
        List<ShopCart> shopCarts = shopCartMapper.selectListByUserId(userId);
        List<MyCartRespVO> myCartRespList = ShopCartConvert.INSTANCE.convertList(shopCarts);
        if (CollectionUtils.isNotEmpty(myCartRespList)) {
            List<Long> productIds =
                    myCartRespList.stream().map(MyCartRespVO::getProductId).collect(Collectors.toList());
            List<Product> products = appProductService.selectListWithDeleted(productIds);
            Map<Long, Product> productMap =
                    products.stream().collect(Collectors.toMap(Product::getProductId, Function.identity()));
            List<Long> skuIds =
                    myCartRespList.stream().map(MyCartRespVO::getSkuId).collect(Collectors.toList());
            List<ProductAttrValue> skus = productAttrValueMapper.selectListWithDeleted(skuIds);
            Map<Long, ProductAttrValue> skuMap =
                    skus.stream().collect(Collectors.toMap(ProductAttrValue::getSkuId, Function.identity()));
            for (MyCartRespVO cartRespVo : myCartRespList) {
                Product product = productMap.get(cartRespVo.getProductId());
                ProductAttrValue sku = skuMap.get(cartRespVo.getSkuId());

                if (ObjectUtil.isNotNull(product)) {
                    cartRespVo.setProductName(productMap.get(cartRespVo.getProductId()).getProductName());
                    cartRespVo.setIsShow(productMap.get(cartRespVo.getProductId()).getIsShow());
                    cartRespVo.setIsLapse(product.getDeleted());
                    // 取规格图，无则取商品第一张图片
                    String image = sku.getImage();
                    cartRespVo.setImage((image != null && !image.isEmpty()) ? image : product.getImage().split(",")[0]);
                } else {
                    cartRespVo.setIsLapse(CommonWhetherEnum.YES.getValue());
                }
                if (ObjectUtil.isNotNull(sku)) {
                    cartRespVo.setSku(sku.getSku().replace(",", "/"));
                    cartRespVo.setPrice(sku.getPrice());
                    cartRespVo.setIsLapse(ObjectUtil.isNull(cartRespVo.getIsLapse()) || CommonWhetherEnum.NO.getValue().equals(cartRespVo.getIsLapse()) ?
                            sku.getDeleted() : cartRespVo.getIsLapse());
                } else {
                    cartRespVo.setIsLapse(CommonWhetherEnum.YES.getValue());
                }
            }
        }
        return new TableDataInfo(myCartRespList, PageUtils.getTotal(shopCarts));
    }

    @Override
    public void deleteCart(List<Long> cartIds) {
        shopCartMapper.deleteBatchIds(cartIds);
    }

    @Override
    public List<AppOrderCartRespVO> getOrderCartInfo(List<Long> cartIds) {
        return shopCartMapper.getOrderCartInfo(cartIds);
    }

    @Override
    public void cartsPay(List<Long> cartIds, Integer isPay) {
        shopCartMapper.update(null, new LambdaUpdateWrapper<ShopCart>()
                .in(ShopCart::getCartId, cartIds).set(ShopCart::getIsPay, isPay));
    }

    @Override
    public List<ShopCart> selectShopCartByCartIds(List<Long> cartIds) {
        return shopCartMapper.selectList(new LambdaQueryWrapper<ShopCart>().in(ShopCart::getCartId, cartIds));
    }

    @Override
    public void batchInsert(List<ShopCart> list) {
        shopCartMapper.batchInsert(list);
    }

    @Override
    public List<CartCouponRespVO> searchCartAvailableCoupon(String cartIds, Long userId) {
        // 查询可购买的购物车信息
        List<ShopCartRespVO> shopCarts =
                shopCartMapper.getCartInfo(Arrays.asList(cartIds.split(",")));
        List<CartCouponDTO> cartCouponDtoList = new ArrayList<>();
        for (ShopCartRespVO cart : shopCarts) {
            cartCouponDtoList.add(new CartCouponDTO(cart.getProductId(), cart.getSkuId(), cart.getPrice()));
        }
        return appProductCouponRelationService.searchCartCoupon(cartCouponDtoList, null, userId);
    }

}
